import { computed, ref } from "vue";
import { defineStore } from "pinia";
import { isNumber } from "lodash-unified";
import { ArrayUtils } from "../utils";
import { SDEReader } from "./utils/SDEReader";
import { SDEFileUtils } from "./utils/SDEFileUtils";
import type {
  UniverseCategory,
  UniverseConstellation,
  UniverseGroup,
  UniverseRegion,
  UniverseStation,
  UniverseStruct,
  UniverseSystem,
  UniverseType,
} from "./entity";

export const useCacheStore = defineStore(
  "cache",
  () => {
    const regions = ref<UniverseRegion[]>([]);
    const categories = ref<UniverseCategory[]>([]);
    const universeElementMap = computed(() => {
      const map: Record<
        number,
        UniverseStation | UniverseSystem | UniverseConstellation | UniverseStruct | UniverseRegion
      > = {};
      regions.value.forEach((region) => {
        map[region.region_id] = region;
        region.constellations.forEach((constellation) => {
          map[constellation.constellation_id] = constellation;
          constellation.systems.forEach((system) => {
            map[system.system_id] = system;
            system.structs.forEach((struct) => {
              map[struct.structure_id] = struct;
            });
            system.stations.forEach((station) => {
              map[station.station_id] = station;
            });
          });
        });
      });
      return map;
    });
    const categoryMap = computed(() => {
      return ArrayUtils.toMap(categories.value, (e) => e.id);
    });
    const groups = computed(() => categories.value.flatMap((c) => c.children));
    const groupMap = computed(() => {
      return ArrayUtils.toMap(groups.value, (e) => e.id);
    });

    const types = ref<UniverseType[]>([]);
    const typeMap = computed(() => {
      return ArrayUtils.toMap(types.value, (e) => e.id);
    });

    const typeNameMap = computed(() => {
      return ArrayUtils.toMap(types.value, (e) => e.name);
    });

    const systemMap = computed(() => {
      return ArrayUtils.toMap(
        regions.value.flatMap((region) => region.constellations.flatMap((constellation) => constellation.systems)),
        (e) => e.system_id
      );
    });

    const init = async () => {
      types.value = SDEReader.readUniverseType();
      categories.value = SDEReader.readCategories();
      const materialsMap = ArrayUtils.toMap(SDEReader.readUniverseTypeMaterials(), (e) => e.id);
      const blueprints = SDEReader.readBlueprints();
      const blueprintsMap = ArrayUtils.toMap(blueprints, (e) => e.id);
      //蓝图制造产物映射表
      const blueprintOutputMap = ArrayUtils.toMap(
        blueprints.filter((e) => e.manufacturing?.products?.length! > 0),
        (e) => e.manufacturing!.products![0]!.id
      );
      const reactionMap = ArrayUtils.toMap(
        SDEReader.readBlueprints().filter((e) => e.reaction?.products?.length! > 0),
        (e) => e!.reaction!.products![0].id
      );
      regions.value = await SDEReader.readUniverseRegions();

      const plantSchematicMap = ArrayUtils.toMap(SDEReader.readPlantSchematics(), (e) => e.output.id);

      types.value.forEach((type) => {
        const group = groupMap.value.get(type.groupId)!;
        //因为资源用的是欧服的和国服有差异所以会有部分未更新的数据需要排除
        if (!group) {
          return;
        }
        type.blueprint = blueprintOutputMap.get(type.id) ?? blueprintsMap.get(type.id);
        if (type.blueprint) {
          type.blueprint.type = type;
        }
        type.parent = group;
        group.children.push(type);
        const materials = materialsMap.get(type.id);
        if (materials) {
          type.materials = materials?.materials.map((e) => ({
            type: typeMap.value.get(e.id)!,
            quantity: e.quantity,
          }));
          type.productQuantity = 1;
        }
        if (!type.materials) {
          const reaction = reactionMap.get(type.id);
          if (reaction?.reaction?.materials) {
            type.productQuantity = reaction.reaction.products![0].quantity;
            type.materials = reaction.reaction.materials.map((e) => ({
              type: typeMap.value.get(e.id)!,
              quantity: e.quantity,
            }));
          }
        }

        if (!type.materials) {
          const plantSchematic = plantSchematicMap.get(type.id);
          if (plantSchematic) {
            type.productQuantity = plantSchematic.output.quantity;
            type.materials = plantSchematic.inputs.map((e) => ({
              type: typeMap.value.get(e.id)!,
              quantity: e.quantity,
            }));
          }
        }
      });
      syncIcon().then();
    };

    const getCategory = (id: number): UniverseCategory | undefined => {
      return categoryMap.value.get(id);
    };
    const getGroup = (id: number): UniverseGroup | undefined => {
      return groupMap.value.get(id);
    };

    const getSystem = (id: number) => {
      return systemMap.value.get(id);
    };
    const getType = (id: number | string): UniverseType | undefined => {
      if (isNumber(id)) {
        return typeMap.value.get(id);
      }
      return typeNameMap.value.get(id);
    };
    const syncIcon = async () => {
      for (const universeType of types.value) {
        try {
          if (await SDEFileUtils.saveImage(universeType.id)) {
            console.warn(`${universeType.name} 图标同步成功`);
          }
        } catch (e: any) {
          console.warn(`${universeType.name} 图标同步失败`, e.message);
        }
      }
    };
    return { init, types, groups, categories, regions, universeElementMap, getCategory, getGroup, getType, getSystem };
  },
  {
    persist: {
      paths: ["universeElementMap"],
      storage: localStorage,
    },
  }
);
